import os

def generate_code(table):

    table_name = table.__tablename__.rstrip("s") if table.__tablename__[-1]=="s" else table.__tablename__

    # 输出文件夹
    out_folder_path = "./code/"

    # api层文件夹
    api_folder = "lms_api"
    # model所在文件夹
    model_folder = "canvas_new"

    # 输出文件命名
    route_file_name = "route_{}.py".format(table_name)
    api_file_name = "api_{}.py".format(table_name)
    api_file_import = "api_{}".format(table_name)
    serive_file_import = "service_{}".format(table_name)
    service_file_name = "service_{}.py".format(table_name)
    list_markdown = "{}_list.md".format(table_name)
    add_markdown = "{}_add.md".format(table_name)
    update_markdown = "{}_update.md".format(table_name)
    delete_markdown = "{}_delete.md".format(table_name)

    # api层函数命名
    api_func_list_name = "Api{}s".format(table.__name__)
    api_func_add_name = "Api{}Add".format(table.__name__)
    api_func_update_name = "Api{}Update".format(table.__name__)
    api_func_delete_name = "Api{}Delete".format(table.__name__)

    # service层函数命名
    service_func_name = "Service{}".format(table.__name__)
    service_func_list_name = table_name + 's'
    service_func_add_name = table_name + '_add'
    service_func_update_name = table_name + '_update'
    service_func_delete_name = table_name + '_delete'

    # route-url命名
    blue_print = "/api/v1"
    list_url = "/" + table_name.replace('_', "/") + "s"
    add_url = "/"+ table_name.replace('_', "/") + "/add"
    update_url = "/" + table_name.replace('_', "/") + "/<int:id>"
    delete_url = update_url

    def generate_route_code():
        code = """# -*- coding: utf-8 -*-\n"""
        code += """from . import restful_api as api\n"""
        code += """from app.{}.apis import {}\n""".format(api_folder, api_file_import)
        code += """\n\n"""
        code += """#------{}模块------\n""".format(table.chinese_name())
        code += """# {}列表\n""".format(table.chinese_name())
        code += """api.add_resource({a}.{b}, '{c}', endpoint='{b}')\n""".format(a=api_file_import, b=api_func_list_name, c=list_url)
        code += """# {}添加\n""".format(table.chinese_name())
        code += """api.add_resource({a}.{b}, '{c}', endpoint='{b}')\n""".format(a=api_file_import, b=api_func_add_name, c=add_url)
        code += """# {}修改\n""".format(table.chinese_name())
        code += """api.add_resource({a}.{b}, '{c}', endpoint='{b}')\n""".format(a=api_file_import, b=api_func_update_name, c=update_url)
        code += """# {}删除\n""".format(table.chinese_name())
        code += """api.add_resource({a}.{b}, '{c}', endpoint='{b}')\n""".format(a=api_file_import, b=api_func_delete_name, c=delete_url)
        return code

    def generate_api_code():
        code = """# -*- coding: utf-8 -*-\n"""
        code += """from flask_restful import Resource, reqparse\n"""
        code += """from app.{}.services.{} import {}\n""".format(api_folder, serive_file_import, service_func_name)
        code += """from app_config import RFKL, RFVL\n"""
        code += """\n"""
        code += api_list_code()
        code += """\n\n"""
        code += api_add_code()
        code += """\n\n"""
        code += api_update_code()
        code += """\n\n"""
        code += api_delete_code()
        return code

    def api_list_code():
        code = """"""
        code += """class {}(Resource):\n""".format(api_func_list_name)
        code += """\t# {}列表\n""".format(table.chinese_name())
        code += """\tdef __init__(self):\n"""
        code += """\t\tself.reqparse = reqparse.RequestParser()\n"""
        code += """\t\tself.reqparse.add_argument('page', type=int, default=1, help='页数错误')\n"""
        code += """\t\tself.reqparse.add_argument('per_page', type=int, default=20, help='每页展示个数错误')\n"""
        code += add_argument_code()
        code += """\t\tsuper({}, self).__init__()\n""".format(api_func_list_name)
        code += """\n"""
        code += """\tdef get(self):\n"""
        code += """\t\targs = self.reqparse.parse_args(strict=True)\n"""
        code += """\t\targs_filter = dict(filter(lambda x: not (x[0] in RFKL or x[1] in RFVL), args.items()))\n"""
        code += """\t\treturn {}().{}(**args_filter)\n""".format(service_func_name, service_func_list_name)
        return code

    def api_add_code():
        code = """"""
        code += """class {}(Resource):\n""".format(api_func_add_name)
        code += """\t# {}添加\n""".format(table.chinese_name())
        code += """\tdef __init__(self):\n"""
        code += """\t\tself.reqparse = reqparse.RequestParser()\n"""
        code += add_argument_code("add")
        code += """\t\tsuper({}, self).__init__()\n""".format(api_func_add_name)
        code += """\n"""
        code += """\tdef post(self):\n"""
        code += """\t\targs = self.reqparse.parse_args(strict=True)\n"""
        code += """\t\targs_filter = dict(filter(lambda x: not (x[0] in RFKL or x[1] in RFVL), args.items()))\n"""
        code += """\t\treturn {}().{}(**args_filter)\n""".format(service_func_name, service_func_add_name)
        return code

    def api_update_code():
        code = """"""
        code += """class {}(Resource):\n""".format(api_func_update_name)
        code += """\t# {}修改\n""".format(table.chinese_name())
        code += """\tdef __init__(self):\n"""
        code += """\t\tself.reqparse = reqparse.RequestParser()\n"""
        code += add_argument_code()
        code += """\t\tsuper({}, self).__init__()\n""".format(api_func_update_name)
        code += """\n"""
        code += """\tdef put(self, id):\n"""
        code += """\t\targs = self.reqparse.parse_args(strict=True)\n"""
        code += """\t\targs_filter = dict(filter(lambda x: not (x[0] in RFKL or x[1] in RFVL), args.items()))\n"""
        code += """\t\treturn {}().{}(id, **args_filter)\n""".format(service_func_name, service_func_update_name)
        return code

    def api_delete_code():
        code = """"""
        code += """class {}(Resource):\n""".format(api_func_delete_name)
        code += """\t# {}删除\n""".format(table.chinese_name())
        code += """\tdef __init__(self):\n"""
        code += """\t\tsuper({}, self).__init__()\n""".format(api_func_delete_name)
        code += """\n"""
        code += """\tdef delete(self, id):\n"""
        code += """\t\treturn {}().{}(id)\n""".format(service_func_name, service_func_delete_name)
        return code


    def add_argument_code(method="list"):
        args = [x.replace(table.__tablename__+'.', '') for x in eval(table.__table__.c.__str__())]
        for x in ["id", "created_at", "updated_at"]:
            if x in args:
                args.remove(x)
        code = """"""
        for item in args:
            temp = eval("table.{}".format(item))
            code += """\t\tself.reqparse.add_argument('{}'""".format(item)
            code += """, type={}""".format(temp.type.python_type.__name__)
            if temp.default is not None and method=="add":
                if temp.type.python_type.__name__ == "str":
                    code += """, default='{}'""".format(temp.default.arg)
                else:
                    code += """, default={}""".format(temp.default.arg)
            if temp.comment is not None:
                code += """, help='{}输入错误'""".format(temp.comment)
            code += """)\n"""
        return code

    def generate_service_code():
        code = """# -*- coding: utf-8 -*-\n"""
        code += """from . import BaseCommon\n"""
        code += """from app.models.{} import {}\n""".format(model_folder, table.__name__)
        code += """\n"""
        code += """class {}(BaseCommon):\n""".format(service_func_name)
        code += """\tdef __init__(self):\n"""
        code += """\t\tsuper({}, self).__init__()\n""".format(service_func_name)
        code += """\n"""
        code += """\t# {}列表\n""".format(table.chinese_name())
        code += """\tdef {}(self, **data):\n""".format(service_func_list_name)
        code += """\t\tres, total = {}.paginate(**data)\n""".format(table.__name__)
        code += """\t\treturn {"data": {"list": res, "total": total}}\n"""
        code += """\n"""
        code += """\t# {}添加\n""".format(table.chinese_name())
        code += """\tdef {}(self, **data):\n""".format(service_func_add_name)
        code += """\t\tid = self.save_data({}, data)\n""".format(table.__name__)
        code += """\t\treturn {"data": {"id": id}}\n"""
        code += """\n"""
        code += """\t# {}修改\n""".format(table.chinese_name())
        code += """\tdef {}(self, id, **data):\n""".format(service_func_update_name)
        code += """\t\treturn self.update_data_byid({}, id, data)\n""".format(table.__name__)
        code += """\n"""
        code += """\t# {}删除\n""".format(table.chinese_name())
        code += """\tdef {}(self, id):\n""".format(service_func_delete_name)
        code += """\t\treturn self.delete_data({}, dict(id=id))\n""".format(table.__name__)
        return code

    def get_args():
        args = [x.replace(table.__tablename__+'.', '') for x in eval(table.__table__.c.__str__())]
        for x in ["id", "created_at", "updated_at"]:
            if x in args:
                args.remove(x)
        return args


    def generate_list_markdown():
        args = get_args()
        code = """"""
        code += """**简要概述**\n"""
        code += """\n"""
        code += """- {}列表\n""".format(table.chinese_name())
        code += """\n"""
        code += """**请求URL：** \n"""
        code += """- ` {} `\n""".format(blue_print + list_url)
        code += """\n"""
        code += """**请求方式：**\n"""
        code += """- GET\n"""
        code += """\n"""
        code += """**参数：**\n"""
        code += """\n"""
        code += """| 参数名         | 必选 | 类型 | 说明                                              |\n"""
        code += """| :------------- | :--- | :--- | ------------------------------------------------- |\n"""
        code += """| page           | 否   | int  | 页数  默认:1                                      |\n"""
        code += """| per_page       | 否   | int  | 每页个数  默认:20                                 |\n"""
        for item in args:
            temp = eval("table.{}".format(item))
            code += """| {}       | 否   | {}  | {}           |\n""".format(item, temp.type.python_type.__name__, temp.comment)
        code += """\n"""
        code += """**传参示例**\n"""
        code += """\n"""
        code += """```json\n"""
        code += """{\n"""
        code += """\t"page": "xxxx",\n"""
        code += """\t"per_page": "xxxx",\n"""
        for item in args:
            code += """\t"{}": "xxxx",\n""".format(item)
        code += """}\n"""
        code += """```\n"""
        code += """\n"""
        code += """**返回示例**\n"""
        code += """\n"""
        code += """``` json\n"""
        code += """{\n"""
        code += """\t"errcode": 0,\n"""
        code += """\t"errmsg": 200\n"""
        code += """}\n"""
        code += """```"""
        return code

    def generate_add_markdown():
        args = get_args()
        code = """"""
        code += """**简要概述**\n"""
        code += """\n"""
        code += """- {}添加\n""".format(table.chinese_name())
        code += """\n"""
        code += """**请求URL：** \n"""
        code += """- ` {} `\n""".format(blue_print + add_url)
        code += """\n"""
        code += """**请求方式：**\n"""
        code += """- POST\n"""
        code += """\n"""
        code += """**参数：**\n"""
        code += """\n"""
        code += """| 参数名         | 必选 | 类型 | 说明                                              |\n"""
        code += """| :------------- | :--- | :--- | ------------------------------------------------- |\n"""
        for item in args:
            temp = eval("table.{}".format(item))
            code += """| {}       | 否   | {}  | {}           |\n""".format(item, temp.type.python_type.__name__, temp.comment)
        code += """\n"""
        code += """**传参示例**\n"""
        code += """\n"""
        code += """```json\n"""
        code += """{\n"""
        for item in args:
            code += """\t"{}": "xxxx",\n""".format(item)
        code += """}\n"""
        code += """```\n"""
        code += """\n"""
        code += """**返回示例**\n"""
        code += """\n"""
        code += """``` json\n"""
        code += """{\n"""
        code += """\t"errcode": 0,\n"""
        code += """\t"errmsg": 200\n"""
        code += """}\n"""
        code += """```"""
        return code

    def generate_update_markdown():
        args = get_args()
        code = """"""
        code += """**简要概述**\n"""
        code += """\n"""
        code += """- {}修改\n""".format(table.chinese_name())
        code += """\n"""
        code += """**请求URL：** \n"""
        code += """- ` {} `\n""".format(blue_print + update_url)
        code += """\n"""
        code += """**请求方式：**\n"""
        code += """- PUT\n"""
        code += """\n"""
        code += """**参数：**\n"""
        code += """\n"""
        code += """| 参数名         | 必选 | 类型 | 说明                                              |\n"""
        code += """| :------------- | :--- | :--- | ------------------------------------------------- |\n"""
        for item in args:
            temp = eval("table.{}".format(item))
            code += """| {}       | 否   | {}  | {}           |\n""".format(item, temp.type.python_type.__name__, temp.comment)
        code += """\n"""
        code += """**传参示例**\n"""
        code += """\n"""
        code += """```json\n"""
        code += """{\n"""
        for item in args:
            code += """\t"{}": "xxxx",\n""".format(item)
        code += """}\n"""
        code += """```\n"""
        code += """\n"""
        code += """**返回示例**\n"""
        code += """\n"""
        code += """``` json\n"""
        code += """{\n"""
        code += """\t"errcode": 0,\n"""
        code += """\t"errmsg": 200\n"""
        code += """}\n"""
        code += """```"""
        return code

    def generate_delete_markdown():
        args = get_args()
        code = """"""
        code += """**简要概述**\n"""
        code += """\n"""
        code += """- {}删除\n""".format(table.chinese_name())
        code += """\n"""
        code += """**请求URL：** \n"""
        code += """- ` {} `\n""".format(blue_print + delete_url)
        code += """\n"""
        code += """**请求方式：**\n"""
        code += """- DELETE\n"""
        code += """\n"""
        code += """**返回示例**\n"""
        code += """\n"""
        code += """``` json\n"""
        code += """{\n"""
        code += """\t"errcode": 0,\n"""
        code += """\t"errmsg": 200\n"""
        code += """}\n"""
        code += """```"""
        return code


    if not os.path.exists(out_folder_path):
        os.mkdir(out_folder_path)

    for f in os.listdir(out_folder_path):
         path_file2 =os.path.join(out_folder_path,f)
         if os.path.isfile(path_file2):
             os.remove(path_file2)

    with open(out_folder_path + api_file_name, 'w') as file_object:
        file_object.write(generate_api_code())

    with open(out_folder_path + service_file_name, 'w') as file_object:
        file_object.write(generate_service_code())

    with open(out_folder_path + route_file_name, 'w') as file_object:
        file_object.write(generate_route_code())

    with open(out_folder_path + list_markdown, 'w') as file_object:
        file_object.write(generate_list_markdown())

    with open(out_folder_path + add_markdown, 'w') as file_object:
        file_object.write(generate_add_markdown())

    with open(out_folder_path + update_markdown, 'w') as file_object:
        file_object.write(generate_update_markdown())

    with open(out_folder_path + delete_markdown, 'w') as file_object:
        file_object.write(generate_delete_markdown())